package servlets;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.Date;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Random;
import java.util.Set;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import parsing.Element;
import parsing.Pars_XLS;
import myJDBC.lowLevel.Attributes;
import myJDBC.lowLevel.ObjectTypes;
import myJDBC.lowLevel.Objects;
import myJDBC.lowLevel.Params;
import myJDBC.*;
import constants.ListValueConstants;

import java.io.File;
import java.io.File.*;

import jxl.read.biff.BiffException;


@WebServlet("/SrvlParsing")
public class SrvlParsing extends HttpServlet {
	private static final long serialVersionUID = 1L;
	File uploadetFile = null;   
	
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
  	int id = -1, k=0;
 
	String showpars = null;
  	
	boolean isMultipart = ServletFileUpload.isMultipartContent(request);
	        response.setContentType("text/html");
	        PrintWriter out = response.getWriter();
	if (!isMultipart) {
	    response.sendError(HttpServletResponse.SC_BAD_REQUEST);
	    return;
	}
	DiskFileItemFactory factory = new DiskFileItemFactory();
	factory.setSizeThreshold(1024*1024);
	
	
	File tempDir = (File)getServletContext().getAttribute("javax.servlet.context.tempdir");
    factory.setRepository(tempDir);
    
    ServletFileUpload upload = new ServletFileUpload(factory);
    
	try {
         List items = upload.parseRequest(request);
         Iterator iter = items.iterator();
         while (iter.hasNext()) {
              FileItem item = (FileItem) iter.next();

               if (!item.isFormField()) {
                   String types = null;
                  
                   types = item.getName().substring(item.getName().length()-3);
                   
                   if (!(types.toLowerCase().equals("xls"))) {  //РїСЂРѕРІРµСЂРєР° С‚РёРїР°
               	    response.sendError(HttpServletResponse.SC_BAD_REQUEST); 
               	    return;
                 	}
            	   processUploadedFile(item);
                   } else {
                	   if (item.getFieldName().equals("showpars")){

                		   showpars = item.getString();
                	   }
                	   
                   }
               }	
        } catch (Exception e) {
                e.printStackTrace();
                response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                return;
        }	
    
    	
	    ArrayList<Element> elList;
		try {
			elList = Pars_XLS.parsing(uploadetFile);
			uploadetFile.delete();

		if (showpars!= null){
	    		out.println("<table border='2'>");
	    }
		for (Element me : elList){
			if (me.getType().equals("port")){
	    		insertObject(me, showpars, out);
			}
		}

    	out.println("</table>"); 	
    	out.println("<form method='get' action='privateOffice'><button type='submit'>privateOffice</button></form>");
		} catch (BiffException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
	
	private void processUploadedFile(FileItem item) throws Exception {
       Random random = new Random();
       do{
         String path = getServletContext().getRealPath(random.nextInt() + item.getName());	
         uploadetFile = new File(path);	
         }while(uploadetFile.exists());
         //СЃРѕР·РґР°С‘Рј РІСЂРµРјРµРЅРЅС‹Р№ С„Р°Р№Р»
       uploadetFile.createNewFile();
       item.write(uploadetFile);
      }
	
	
	
	private Map<Integer, Integer> insertObject(Element element, String showpars, PrintWriter out) throws SQLException, ParseException {
		Map<Integer, Integer> parentMap = null;
		ArrayList<String> al = ObjectTypes.returnObjectTypes_Id_Name_ParId(); 
		Map<Integer, Integer> elMap = Objects.returnMapObjInfo(element.getName());
		if (!(element.getParent() == null)) {
			parentMap = insertObject(element.getParent(), showpars, out);
		}
		if (!(parentMap == null)){
			Set<Map.Entry<Integer, Integer>> parSet = parentMap.entrySet();
			for (Map.Entry<Integer, Integer> parObj : parSet){
				Map<String, Integer> childrens = Objects.returnChildrensName(parObj.getKey());
                if (!(childrens.containsKey(element.getName()))){

        				if(al.contains(element.getType())) {
        			        
        				       	 int  id = Integer.parseInt(al.get(al.indexOf(element.getType())-1));
        			    		  id = Objects.createObject(element.getName(), "" , id, parObj.getKey());
        			    		    if (showpars!= null){
        			    		    out.println( "<tr><td>" + element.getName()
        			    						   + "</td><td>" + element.getType().toLowerCase(Locale.ENGLISH)
        			    						   + "</td></tr>");	
        			    		    }
        			    		    if(!(element.getAttribute().isEmpty())){
        			    		        
        			    		    	if (element.getAttribute().containsKey("status")) {
        			    		    	    ArrayList<String> attrIdList = Attributes.returnAttribute("status");
        			    		    	    int attrId = Integer.parseInt(attrIdList.get(attrIdList.indexOf("status")-1));
        			    		    	    if (element.getAttributeValue("status").equals("available")) {
        			    		    	    	Params.createParamArray(attrId, id, ListValueConstants.port_available);
        			    		    	    }
        			    		    	    if (element.getAttributeValue("status").equals("active")) {
        			    		    	    	Params.createParamArray(attrId, id, ListValueConstants.port_active);
        			    		    	    }
        			    		    	}
        			    		    	if (element.getAttribute().containsKey("date")) {
            			    		    	ArrayList<String> attrIdList = Attributes.returnAttribute("date");
            			    		    	int attrId = Integer.parseInt(attrIdList.get(attrIdList.indexOf("date")-1));
            			    		        Params.createParamDate(attrId, id, element.getAttributeValue("date"), "MM/DD/YYYY");
            			    		    }
        			    		    }
        			    		    	
                        	elMap = null;
                        	elMap = new HashMap<Integer,Integer>();
                        	elMap.put(id,parObj.getKey());
                        	
                        	if (element.getType().equals("port")) {
                        		countPorts(parObj.getKey());
                        	}
                        	
                        	break;
        				
        			    }
                } else {
                	elMap = null;
                	elMap = new HashMap<Integer,Integer>();
                	elMap.put(childrens.get(element.getName()),parObj.getKey());
                	if(!(element.getAttribute().isEmpty())){		    		    
	    		    	
                	    if (element.getAttribute().containsKey("status")) {
                		    ArrayList<String> attrIdList = Attributes.returnAttribute("status");
	    		    	    int attrId = Integer.parseInt(attrIdList.get(attrIdList.indexOf("status")-1));
	    		    	
	    		         	if (Params.returnArrValue(attrId, childrens.get(element.getName())) == null){    		         		
	    		                if (element.getAttributeValue("status").equals("available")) {
		    		    	    	Params.createParamArray(attrId, childrens.get(element.getName()), ListValueConstants.port_available);
		    		    	    }
		    		    	    if (element.getAttributeValue("status").equals("active")) {
		    		    	    	Params.createParamArray(attrId, childrens.get(element.getName()), ListValueConstants.port_active);
		    		    	    }
	    		        	} else {
	    		        		 if (element.getAttributeValue("status").equals("available")) {
			    		    	    	Params.changeValueId(childrens.get(element.getName()), attrId, ListValueConstants.port_available);
			    		    	 }
			    		    	 if (element.getAttributeValue("status").equals("active")) {
			    		    	    	Params.changeValueId(childrens.get(element.getName()), attrId, ListValueConstants.port_active);
			    		    	 }
		    		            
	    		        	}
                	    }
	    		    	
	    		    	if (element.getAttribute().containsKey("date")) {
	    		    		ArrayList<String> attrIdList = Attributes.returnAttribute("date");
	    		    	    int attrId = Integer.parseInt(attrIdList.get(attrIdList.indexOf("date")-1));
	    		    	
	    		         	if (Params.returnDate(attrId, childrens.get(element.getName())).isEmpty()){
	    		                Params.createParamDate(attrId, childrens.get(element.getName()), element.getAttributeValue("date"),"MM/DD/YYYY");
	    		        	} else {
		    		            Params.UpdateParamDate(attrId, childrens.get(element.getName()), element.getAttributeValue("date"), "MM/DD/YYYY");
	    		        	}
		    		    }
	    		    }
                	break;
                }
			}
		} else {
			if(al.contains(element.getType())) {
				ArrayList<String> objectList = Objects.returnObjWithObjTypeName(element.getType());
				if (!(objectList.contains(element.getName()))){
		       	  int  id = Integer.parseInt(al.get(al.indexOf(element.getType())-1));
	    		  id = Objects.createObject(element.getName(), "" , id, -1);
	    		  if (showpars!= null){
		    		    out.println( "<tr><td>" + element.getName()
		    						   + "</td><td>" + element.getType().toLowerCase(Locale.ENGLISH)
		    						   + "</td></tr>");	
		          }
	    		  if(!(element.getAttribute().isEmpty())){
		    		    
	    			  if (element.getAttribute().containsKey("status")) {
	    		    	    ArrayList<String> attrIdList = Attributes.returnAttribute("status");
	    		    	    int attrId = Integer.parseInt(attrIdList.get(attrIdList.indexOf("status")-1));
	    		    	    if (element.getAttributeValue("status").equals("available")) {
	    		    	    	Params.createParamArray(attrId, id, ListValueConstants.port_available);
	    		    	    }
	    		    	    if (element.getAttributeValue("status").equals("active")) {
	    		    	    	Params.createParamArray(attrId, id, ListValueConstants.port_active);
	    		    	    }
	    		    	}
	    		      if (element.getAttribute().containsKey("date")) {
		    		    	ArrayList<String> attrIdList = Attributes.returnAttribute("date");
		    		    	int attrId = Integer.parseInt(attrIdList.get(attrIdList.indexOf("date")-1));
		    		        Params.createParamDate(attrId, id, element.getAttributeValue("date"),"MM/DD/YYYY");
		    		    }
	    		  }
            	elMap = null;
        	    elMap = new HashMap<Integer,Integer>();
        	    elMap.put(id, null);
				}
		    }
		}
		return elMap;
	
		
	}
	
	
	
    private void countPorts(Integer objId) throws SQLException {
        
 			ArrayList<String> attrIdList = Attributes.returnAttribute("count");
    	    int attrId = Integer.parseInt(attrIdList.get(attrIdList.indexOf("count")-1));
    	    String countValue = Params.returnVarchNumb(attrId, objId);

        	    if (countValue.isEmpty()) {
                    Params.createParamVarchNumb(attrId, objId, Integer.toString(1));
        	    } else {
    	            Params.UpdateParamVarchNumb(attrId, objId, Integer.toString(Integer.parseInt(countValue) + 1));
        	    }
        
        	}
		
	


}
